package net.homelinux.chaoswg.io.renga.core.gui;

import java.awt.BorderLayout;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.InputStream;

import javax.imageio.ImageIO;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.filechooser.FileFilter;

import net.homelinux.chaoswg.io.renga.core.gui.operations.CompositeOperation;
import net.homelinux.chaoswg.io.renga.core.gui.operations.reader.GlobalIO;
import net.homelinux.chaoswg.io.renga.core.registries.GlobalPropertyRegistry;
import net.homelinux.chaoswg.io.renga.krypto.gui.operations.LoopOperation;

//The GUI is a farely easy job 
public class GUI extends JFrame {
    final GUI _this = this;
    private File filename = null;


    //We need to hold the composite we are maintaining
    final CompositeOperation co;

    //Which is given us in the constructor
    public GUI (final CompositeOperation co) {
        //We set a title 
        super ("Renga " + co.getName());
        //Hold the operation
        this.co = co;
        //Tell the operations that they are visible
        this.co.getControl().setAllVisible(true);


        //Load and set a nice image
        Image image = null;

        try {
            InputStream istream = ((ClassLoader)GlobalPropertyRegistry.getGlobalPropertyRegistry().getProperty("ClassLoader")).getResourceAsStream("images/Renga_RedCircle_DropShadow.png");
            //image = Toolkit.getDefaultToolkit().getImage("/home/Io/users/martin/Symbole/Renga_RedCircle_DropShadow.png");
            image = loadImage(istream);
        } catch (Exception ex) {
            System.err.println (ex);
        }
        if (image != null) {
            setIconImage (image);
        }

        //Add the core components
        addAll ();
        //the listeners
        addListeners();
        //resize nicely
        pack ();

        setLocationRelativeTo(null);

        //Put ourself in the middle of the monitor
//      setLocationRelativeTo(null);
        //And go public
        setVisible(true);
    }

    private void addAll () {
        this.setJMenuBar(new GUIMenuBar (_this));
        //A toppanel with buttons does most of the work for addition and removal
        this.getContentPane().add(new TopPanel (_this, co), BorderLayout.NORTH); // Buttons
        //The center shows what there is to see
        this.getContentPane().add(new JScrollPane (new DrawingArea (co)), BorderLayout.CENTER); // DiagramView for component
        //And at the bottom a statusbar shows us what could be done
        this.getContentPane().add(new StatusBar (co.getControl()), BorderLayout.SOUTH); //Statusbar for components
    }


    private Image loadImage (InputStream istream) {
        BufferedImage img = null;
        try {
            img = ImageIO.read (istream);
        } catch (final Exception excp) {
            System.err.println (excp);
        }

        return img;
    }

    //And we just need to listen if we are quit
    private void addListeners () {
        this.addWindowListener(new WindowAdapter () {
            public void windowClosing (WindowEvent event) {
                //And in that case we simple free all the resources we currently hold
                //done

                _this.exit ();
            }
        });
    }

    public void exit () {
        _this.co.getControl().setAllVisible(false);
        _this.dispose();
    }

    public void open () {
        try {
            JFileChooser jfc = new JFileChooser ();
            File f;

            jfc.setFileFilter(new FileFilter () {
                public boolean accept (File f) {
                    return f.toString().endsWith(".renga") || f.isDirectory();
                }

                @Override
                public String getDescription() {
                    return "Renga-Files";
                }
            });
            int returnValue = jfc.showOpenDialog(_this);

            if (returnValue == JFileChooser.APPROVE_OPTION) {
                f = jfc.getSelectedFile();
                GlobalIO gr = new GlobalIO ();
                GUI gui = new GUI (((CompositeOperation)gr.apply(f).get(0)));
                gui.setFilename(f);
            }
        }catch (Exception excp) {
            JOptionPane.showMessageDialog(this, "Sorry your request couldn't be processed. And I don't know why", "Strange error", JOptionPane.ERROR);
        }
    }

    public void save () {
        if (this.co instanceof LoopOperation) {
            JOptionPane.showMessageDialog(_this, "Sorry you can't save loops (at the moment)", "Loop Operation", JOptionPane.ERROR_MESSAGE);
            return;
        }
        if (filename == null) {
            saveAs ();
        } else {
            new GlobalIO ().write(co, filename);
        }
    }

    public void saveAs () {
        if (this.co instanceof LoopOperation) {
            JOptionPane.showMessageDialog(_this, "Sorry you can't save loops (at the moment)", "Loop Operation", JOptionPane.ERROR_MESSAGE);
            return;
        }

        JFileChooser jfc = new JFileChooser ();

        jfc.setFileFilter(new FileFilter () {
            public boolean accept (File f) {
                return f.toString().endsWith(".renga") || f.isDirectory();
            }

            public String getDescription() {
                return "Renga-Files";
            }
        });

        int returnValue = jfc.showSaveDialog(_this);

        if (returnValue == JFileChooser.APPROVE_OPTION) {
            filename = jfc.getSelectedFile();

            if (! (filename.toString().endsWith(".renga"))) {
                filename = new File (filename.toString().concat(".renga"));
            }

            if (! filename.exists() || (JOptionPane.showConfirmDialog(_this, "Are you sure", "Override " + filename.getName(), JOptionPane.YES_NO_OPTION) == 
                JOptionPane.YES_OPTION)) {
                GlobalIO gr = new GlobalIO ();
                if (! (gr.write(co, filename))) {
                    System.err.println("AHHH");
                }
            }
        }

    }

//  public static void main (String... args) {
//  init();
//  new GUI(new CompositeOperation(new Control ()));
//  }


    public File getFilename() {
        return filename;
    }

    public void setFilename(File filename) {
        this.filename = filename;
    }
}
